package com.xiyuan.smartutils;

/**
 * the description for class DynamicEnumUtils
 *
 * @author xiyuan-lgz 2023-03-14 @version v1.0.0 新建与整理
 */
@SuppressWarnings("unchecked")
public final class EnumUtils {

//
//    private static ReflectionFactory reflectionFactory = ReflectionFactory.getReflectionFactory();
// //
// //
//    private static ConstructorAccessor getConstructorAccessor(Class<?> enumClass, Class<?>[] additionalParameterTypes)
//            throws NoSuchMethodException {
//        Class<?>[] parameterTypes = new Class[additionalParameterTypes.length + 2];
//        parameterTypes[0] = String.class;
//        parameterTypes[1] = int.class;
//        System.arraycopy(additionalParameterTypes, 0, parameterTypes, 2, additionalParameterTypes.length);
//        return reflectionFactory.newConstructorAccessor(enumClass.getDeclaredConstructor(parameterTypes));
//    }
//    //(enumType, enumName, values.size(), additionalTypes, additionalValues);
//    private static Object makeEnum(Class<?> enumClass, String value, int ordinal, Class<?>[] additionalTypes,
//                                   Object[] additionalValues) throws Exception {
//        Object[] params = new Object[additionalValues.length + 2];
//        params[0] = value;
//        params[1] = Integer.valueOf(ordinal);
//        System.arraycopy(additionalValues, 0, params, 2, additionalValues.length);
//        return enumClass.cast(getConstructorAccessor(enumClass, additionalTypes).newInstance(params));
//    }
//
//    public static <T extends Enum>  T createEnum(Class<T> enumType, String name) {
//        if (!Enum.class.isAssignableFrom(enumType)) {
//            throw new RuntimeException("class " + enumType + " is not an instance of Enum");
//        }
//
//        if (!Validates.isJavaNameIdentifier(name)) {throw new IllegalArgumentException("invalid enum name " + name);}
//        T[] values = enumType.getEnumConstants();
//        if (values != null) {
//            for (int i = 0; i < values.length; i++) {
//                T value = values[i];
//                if (value.name().equals(name)) {
//                    return value;
//                }
//            }
//        }
//
//        // 0. Sanity checks
//        if (!Enum.class.isAssignableFrom(enumType)) {
//            throw new RuntimeException("class " + enumType + " is not an instance of Enum");
//        }
//
//        // 1. Lookup "$VALUES" holder in enum class and get previous enum instances
//        Field valuesField = null;
//        Field[] fields = enumType.getDeclaredFields();
//        for (Field field : fields) {
//            if (field.getName().contains("$VALUES")) {
//                valuesField = field;
//                break;
//            }
//        }
//        AccessibleObject.setAccessible(new Field[] {valuesField }, true);
//
//
//        // 创建枚举实例
//        return null;
//    }
//
//
//
//
//
//    public enum MyEnum {
//        KEY1("key1","第1个"),
//        KEY2("key2","第2个"),
//        KEY3("key3","第3个"),
//        ;
//        private String key;
//        private String displayName;
//        MyEnum(String key,String  displayName){
//            this.key = key;
//            this.displayName = displayName;
//        }
//        @Override
//        public String toString() {
//            return "org.example.testio.enums.MyEnum{" +
//                    "key='" + key + '\'' +
//                    ", displayName='" + displayName + '\'' +
//                    '}';
//        }
//    }
//    /**
//     * 新增枚举值
//     *
//     * @param clazz      枚举类型
//     * @param fieldClass 枚举字段类型，第一个是枚举名类型String
//     * @param fieldNames 枚举字段，第一个是枚举名
//     * @throws Exception
//     */
//    public static <T extends Enum> void addEnum(Class<T> clazz, Class[] fieldClass, String[] fieldNames) throws
//                                                                                                         Exception {
//        ReflectionFactory reflectionFactory = ReflectionFactory.getReflectionFactory();
//        //name,ordinal,其他自定义字段
//        List<Class> allFieldClass = new ArrayList<>(fieldClass.length + 1);
//        allFieldClass.add(fieldClass[0]);
//        allFieldClass.add(int.class);
//        for (int i = 1; i < fieldClass.length; i++) {
//            allFieldClass.add(fieldClass[i]);
//        }
//        Class[] classes = allFieldClass.toArray(new Class[]{});
//        Constructor<T> constructor = clazz.getDeclaredConstructor(classes);
//        ConstructorAccessor constructorAccessor = reflectionFactory.newConstructorAccessor(constructor);
//        List<Object> allFields = new ArrayList<>(fieldNames.length + 1);
//        allFields.add(fieldNames[0]);
//        allFields.add(0);
//        for (int i = 1; i < fieldNames.length; i++) {
//            allFields.add(fieldNames[i]);
//        }
//        T newEnum = (T) constructorAccessor.newInstance(allFields.toArray());
//        System.out.println("新增枚举：" + newEnum);
//        Field $VALUES = clazz.getDeclaredField("$VALUES");
//        $VALUES.setAccessible(true);
//        Field modifiersField = Field.class.getDeclaredField("modifiers");
//        modifiersField.setAccessible(true);
//        int modifiers = modifiersField.getInt($VALUES);
//        modifiers &= ~Modifier.FINAL;
//        modifiersField.setInt($VALUES, modifiers);
//        FieldAccessor fieldAccessor = reflectionFactory.newFieldAccessor($VALUES, false);
//        T[] ts = (T[]) fieldAccessor.get(clazz);
//        List<T> list = new ArrayList<>(Arrays.asList(ts));
//        list.add(newEnum);
//        fieldAccessor.set(clazz, list.toArray(ts));
//    }
// //   public static void main(String[] args) throws Exception {
// //        EnumUtil.addEnum(MyEnum.class,new Class[]{String.class,String.class,String.class},new String[]{"KEY4","key4","第4个"});
// //        Arrays.stream(MyEnum.values()).forEach(System.out::println);
// //    }
// //
// //    public static void main(String[] args) {
// //
// ////        EnumUtils.addEnum(T.class, "pppp", new Class[]{
// ////                String.class, String.class, String.class, String.class, String.class,
// ////                double.class, boolean.class, String.class, String.class, String.class
// ////        }, new Object[]{
// ////                "QPS", "pp", "pp", "pp", "pp",
// ////                100d, false, "最大QPS", "avg", "最大QPS"
// ////        });
// ////
// ////        for (T temp : T.values()) {
// ////            System.out.println(temp.getAllName());
// ////        }
// ////
// //    }
}
